<script setup lang="ts" name="GoodsSku">
import { GoodsInfo, Spec, SpecValue } from '@/types/goods'
import bwPowerSet from '@/utils/power-set'

const props = defineProps<{
  goods: GoodsInfo
  skuId?: string // 传了就默认回显高亮某些项, 没传就不高亮 自己选
}>()

const emit = defineEmits<{
  (e: 'changeSku', value: string): void
}>()

// 需求: 点谁谁亮
// 1. 判断当前想是否高亮, 如果高亮了, 取消高亮,
// 2. 如果当前项没有高亮, 高亮当前项且排他(改规格内的)
// 3. 如果禁用了 ,什么都不做
const changeSelected = (item: Spec, sub: SpecValue) => {
  if (sub.disabled) return

  if (sub.selected) {
    sub.selected = false
  } else {
    item.values.forEach((v) => (v.selected = false))
    sub.selected = true
  }

  // console.log('选中的数据:', getSelectedSpec()) // 临时在这里触发一下(最后)
  // 应该是点击了某个选项后, 更新禁用状态
  updateDisabledStatus()

  // 获取用户的选中项, 如果选满了, 应该子传父 告知父组件
  console.log('选中了', getSelectedSpec())
  const res = getSelectedSpec().filter((v) => v)

  if (res.length === props.goods.specs.length) {
    console.log('满了')
    const key = res.join(SPLIT_STR)
    const [skuId] = pathMap[key]
    // console.log(skuId) // 字传父

    emit('changeSku', skuId)
  }
}

const SPLIT_STR = '+'
// 1. filter 筛选有效sku
// 2. map 得到一个sku的选项数组['蓝色','中国','10'] 将来交给bwPowerSet路径集合
// 3. 转换成得到路径字典对象,(键: 黑色+中国; 值: [skuid])
// 封装一个方法 得到路径字典
const getPahtMap = () => {
  // pathMap值用any临时解决
  // pathMap键名师不确定的, 简明的类型是确定的!! 一定是字符串类型
  const pathMap: {
    [key: string]: string[]
  } = {}
  // console.log(props.goods.skus, '过滤前')

  const validSkus = props.goods.skus.filter((item) => item.inventory > 0)
  // console.log(validSkus, '过滤后')

  validSkus.forEach((sku) => {
    // console.log(sku.specs) // 获取每一个有效sku的具体筛选条件
    // 想要获取具体筛选条件的路径集合['红色','中国'] => ['红色'],['中国']
    // 所以, 要对具体筛选条件数组 ,进行转换
    const arr = sku.specs.map((item) => item.valueName)
    // console.log(arr, '需要显示的格式')

    const resArr = bwPowerSet(arr)
    // console.log(resArr, '最后需要的路径集合')

    resArr.forEach((v) => {
      // console.log(v.join(SPLIT_STR), '拼接之后的数据')

      const key = v.join(SPLIT_STR)
      if (key in pathMap) {
        // 键在对象中存在
        pathMap[key].push(sku.id)
      } else {
        // 键在对象中不存在, => 新开一个属性, 值是数组[skuID]
        pathMap[key] = [sku.id]
      }
    })
  })
  return pathMap
}

// const getPahtMap = () => {
//   const pathMap: any = {}
//   const validSkus = props.goods.skus.filter((item) => item.inventory > 0)
//   validSkus.forEach((sku) => {
//     const arr = sku.specs.map((item) => item.valueName)
//     // console.log(arr)
//     // 将映射出来的转换成集合
//     const resArr = bwPowerSet(arr)
//     // console.log(resArr, '转换成集合')
//     // 将里面的数据拼接然后添加上唯一的标识这边使用skuId
//     resArr.forEach((v) => {
//       const key = v.join(SPLIT_STR)
//       if (key in pathMap) {
//         pathMap[key].push(sku.id)
//       } else {
//         pathMap[key] = [sku.id]
//       }
//     })
//   })

//   return pathMap
// }
const pathMap = getPahtMap()
console.log('路径字典', pathMap)

// 封装一个方法获取选中的选项, 约定: 和specs规格数组 保持长度一致, 顺序一致, 方便查找路径字典
const getSelectedSpec = () => {
  const arr: string[] = []

  // 遍历每一个规则, 找到这个规格下的选中项
  props.goods.specs.forEach((item) => {
    const temp = item.values.find((sub) => sub.selected === true)

    //如果找到了, push选项名字; 反之 push ''
    arr.push(temp ? temp.name : '')
  })

  return arr
}

// 封装一个方法, 初始化/点击后 选项的禁用状态的函数
const updateDisabledStatus = () => {
  //先获取选中项数组['', '', '日本'], 然后和每一个选项组成一个筛选条件, 去路径字典中查找
  const selectedArr = getSelectedSpec()
  console.log(selectedArr, '这个是啥')

  // 遍历每一个选项 查找这个选项的name在我们路径字典中是否存在, 存在 disabled fasle ;反之 true
  props.goods.specs.forEach((item, index) => {
    // console.log(item, '111')

    item.values.forEach((sub) => {
      // console.log(sub, '查看sub是啥')

      // 需要将每一个选项和已经确定的筛选条件做组合['', '', '日本'] !!!!!
      // 拷贝一下
      const tempArr = [...selectedArr]
      console.log(tempArr[index], '你是')

      tempArr[index] = sub.name
      const key = tempArr.filter((v) => v).join(SPLIT_STR)
      // console.log(key)

      // if (sub.name in pathMap) {
      //   // 有货的 => 可选 => false
      //   sub.disabled = false
      // } else {
      //   // 没货 => 禁用
      //   sub.disabled = true
      // }
      if (key in pathMap) {
        // 有货的 => 可选 => false
        sub.disabled = false
      } else {
        // 没货 => 禁用
        sub.disabled = true
      }
    })
  })
}

const initSelectedSpec = () => {
  if (!props.skuId) return
  // console.log(props.goods, props.skuId)
  const sku = props.goods.skus.find((item) => item.id === props.skuId)
  // console.log(sku!.specs)
  if (sku) {
    props.goods.specs.forEach((item, index) => {
      // item.values.find()
      // 获取具体筛选条件
      // console.log(sku.specs[index].valueName, 111)

      const temp = sku.specs[index].valueName // '黑色'
      //选项中查找对应名字的项, 让他的selected为true
      const res = item.values.find((item) => item.name === temp)
      res!.selected = true
    })
  }
}
updateDisabledStatus()
initSelectedSpec()

// bug: 珐琅锅商品页面下, 点击二级分类, 这个时候再返回, 珐琅锅的默认禁用没有了???
// 分析: updateDisabledStatus 组件创建时, 触发一次 => 没有清空数据!!!
</script>
<template>
  <div class="goods-sku">
    <!-- 一个规格就是一个dl -->
    <dl v-for="item in goods.specs" :key="item.id">
      <dt>{{ item.name }}</dt>
      <dd>
        <!-- v-for 和 v-if 都要用  但是不能连用 所以要使用template -->
        <template v-for="sub in item.values" :key="sub.name">
          <img
            :class="{ selected: sub.selected, disabled: sub.disabled }"
            @click="changeSelected(item, sub)"
            v-if="sub.picture"
            :src="sub.picture"
            alt=""
          />
          <span
            @click="changeSelected(item, sub)"
            :class="{ selected: sub.selected, disabled: sub.disabled }"
            v-else
            >{{ sub.name }}</span
          >
        </template>
      </dd>
    </dl>
    <!-- <dl>
      <dt>尺寸</dt>
      <dd>
        <span class="disabled">10英寸</span>
        <span class="selected">20英寸</span>
        <span>30英寸</span>
      </dd>
    </dl>
    <dl>
      <dt>版本</dt>
      <dd>
        <span>美版</span>
        <span>港版</span>
      </dd>
    </dl> -->
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
